from typing import Dict, Any, Optional
from sqlalchemy.ext.asyncio import AsyncSession
from core.pagination import paging_data, _CustomPageParams
from fastapi import HTTPException, status

from modules.{{ app_name }}.models.{{ filename }}_model import {{ class_name }}
from modules.{{ app_name }}.schemas.{{ filename }}_schema import {{ class_name }}Create, {{ class_name }}Update
from modules.{{ app_name }}.params.{{ filename }}_params import {{ class_name }}Query
from modules.{{ app_name }}.curd.{{ filename }}_curd import {{ filename }}_dao
from utils.query_builder import build_select_stmt


class {{ class_name }}Service:
    @staticmethod
    async def get_list_with_pagination(db: AsyncSession, query_params: {{ class_name }}Query) -> Dict[str, Any]:
        stmt = build_select_stmt(
            {{ class_name }},
            query_params,
            order_by_desc="id",
            text_like_fields=None,
        )
        params = _CustomPageParams(page=query_params.page, size=query_params.size)
        return await paging_data(db, stmt, params=params)

    @staticmethod
    async def get_by_id(db: AsyncSession, pk: Any) -> Optional[{{ class_name }}]:
        repo = await {{ filename }}_dao.get_by_id(db, pk)
        return repo

    @staticmethod
    async def create(db: AsyncSession, data: {{ class_name }}Create) -> {{ class_name }}:
        # 传递 Pydantic 模型给 DAO，由其内部处理 model_dump
        repo = await {{ filename }}_dao.create(db, data)
        await db.commit()
        await db.refresh(repo)
        return repo

    @staticmethod
    async def update(db: AsyncSession, pk: Any, data: {{ class_name }}Update) -> Optional[{{ class_name }}]:
        # DAO 返回 ORM 实例，避免 UnmappedInstanceError
        repo = await {{ filename }}_dao.update(db, pk, data)
        if not repo:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"记录 {pk} 不存在")
        await db.commit()
        await db.refresh(repo)
        return repo

    @staticmethod
    async def delete(db: AsyncSession, pk: Any) -> bool:
        repo = await {{ filename }}_dao.delete(db, pk)
        if not repo:
            return False
        await db.commit()
        return True